if(typeof(mstar)=="undefined"){
    var mstar = {};
}
function QS_NumberFormatter(val,f,s,dec){
	if(typeof(QS_NumFmt)!="undefined"&&typeof(QS_NumFmt.Fmt2)=="function"){
		return QS_NumFmt.Fmt2(val,false,'',typeof(dec)!="undefined"&&!isNaN(dec)?dec:2);
	}
	if(typeof(dec)!="undefined"&&!isNaN(dec)){
		return parseFloat(val).toFixed(dec);
	}else{
		return val;
	}
}
mstar.flotUtil = {
    floorInBase: function(n, base) {
        return base * Math.floor(n / base);
    },
    colorToRGB:function(colorHex,alpha){
        var c = this.colorType(colorHex);
        if(arguments.length>1){
            return "rgba("+c.r+","+c.g+","+c.b+","+alpha+")";
        }else if(c.t=="rgba"){
            return "rgba("+c.r+","+c.g+","+c.b+","+c.a+")";
        }else{
            return "rgb("+c.r+","+c.g+","+c.b+")";
        }
    },
    colorType:function(colorHex){
        var color={t:"rgb",r:255,g:255,b:255,a:1},result="";
        if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(colorHex)){
            color={t:"h6",r:parseInt(result[1], 16),g:parseInt(result[2], 16),b:parseInt(result[3], 16),a:1};
        }else if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(colorHex)){
            color={t:"h3",r:parseInt(result[1]+result[1], 16),g:parseInt(result[2]+result[2], 16),b:parseInt(result[3]+result[3], 16),a:1};
        }else if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(colorHex)){
            color={t:"rgb",r:parseInt(result[1], 10),g:parseInt(result[2], 10),b:parseInt(result[3], 10),a:1};
        }else if (result = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(colorHex)){
            color={t:"rgba",r:parseInt(result[1], 10),g:parseInt(result[2], 10),b:parseInt(result[3], 10),a:parseFloat(result[4])};
        }
        return color;
    },
    colorRange:function(c){
        return c<0?0:(c>255?255:c);
    },
    avoidSelect:function(){
        if(!$.browser.msie||$.browser.msie&&parseInt($.browser.version)!=8){
            window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty(); 
        }
    }
};
var chartCanvas = function(container, cfg){
    this.container = container;
	this.isIe =$.browser.msie;
    this.cfg = $.extend(true, {
        showX: false,
        showY: false,
		showXScale:true,
		showYScale:true,
		showYPrecent:false,
		showYPlus:false,
		showYScaleNumber:true,
		worldmap:false,
		xLableMinWidth:430,//needRemoveSecondXLable:
		alternateXLable:false,
		xLableCount:-1,
		lineWidth:1,
        canvasWidth: container.width()||500,
        canvasHeight: container.height()||300,
		percision:[0,2],
		lineType:"montain",//line montain abovebelow block,
		align:"right",
		color:{
			line:QS_Style.chart.fillColors.minichartPchart||QS_Style.chart.fillColors.pChart||"#8ab9f3",
			worlmapColors:(typeof(QS_Style.worldMap)=="undefined")?["#DCDCDC"]:QS_Style.worldMap,
			fill:"#666",
			axisColor:QS_Style.flot.grid.tickColor,
			textColor:QS_Style.flot.grid.color,
			blockUp:"#65A125",
			blockDown:"#CA3239",
			blockUpStroke:"#65A125",
            blockDownStroke:"#CA3239",
			blockLine:"#fff"
		}
    }, cfg);
    this.canvas = null;
    this.context = null;
	this.axis={x:{max:0,min:0,scale:0,margin:55},y:{max:0,min:0,scale:0,margin:20,scaleCount:3,scaleList:[],insidePercent:0.05}};
    this.el = null;
	this.data = null;
	this.timeObj = null;
	this.measureTextWidthDom=null;
    this.__init();
};

chartCanvas.prototype = {
	drawWorldMap:function(d){
		var self = this;
		if(!d){
			return;
		}
		this.data = d;
		this._checkConfig();
        this._parseWorldMapData(d);
        this._drawingWorldMap(d);
	},
	setPercision:function(array){
		this.cfg.percision=array;
	},
	setScaleCount:function(count,isY){
		this.axis[isY?"y":"x"]["scaleCount"]=count;
	},
	getPositionByPrice:function(pos){
		return [this.axis.x.getCanvasPositionByPrice(pos[0]),this.axis.y.getCanvasPositionByPrice(pos[1])];
	},
	_parseWorldMapData:function(data){
		var max =0,min=100000,tx=null,ty= null,self = this;
		var extremum = {x:{min:Number.MAX_VALUE,max:Number.MIN_VALUE},y:{min:Number.MAX_VALUE,max:Number.MIN_VALUE}};
		for(var i in data){
			var tempExtremum = {x:{min:Number.MAX_VALUE,max:Number.MIN_VALUE},y:{min:Number.MAX_VALUE,max:Number.MIN_VALUE}};
			for(var j=0;j<data[i].length;j++){
				dx = data[i][j][0];
				dy = data[i][j][1];
				if(extremum.x.max<dx){
					extremum.x.max = dx;
				}
				if(extremum.x.min>=dx){
					extremum.x.min = dx;
				}
				if(extremum.y.max<dy){
					extremum.y.max = dy;
				}
				if(extremum.y.min>=dy){
					extremum.y.min = dy;
				}
			}
		}
		var diffx = extremum.x.max-extremum.x.min;
		var diffy = extremum.y.max-extremum.y.min;
		
        $.extend(true, this.axis.y, {
            max: extremum.y.max,
            min: extremum.y.min,
            scale: (this.cfg.canvasHeight -this.axis.y.margin)/ (extremum.y.max - extremum.y.min),
            getCanvasPositionByPrice: function(p){
                return (p -extremum.y.min)* self.axis.y.scale;//return self.cfg.canvasHeight -self.axis.y.margin - (p -extremum.y.min)* self.axis.y.scale;
            },
			getPriceByCanvasPosition:function(p){
				return (p)/self.axis.y.scale;
			}
        });
        $.extend(true, this.axis.x, {
            max: extremum.x.max,
            min: extremum.x.min,
            scale: (this.cfg.canvasWidth-this.axis.x.margin) / (extremum.x.max - extremum.x.min),
            getCanvasPositionByPrice: function(p){
                return (p -extremum.x.min)* self.axis.x.scale;
            },
			getPriceByCanvasPosition:function(p){
				return p/self.axis.x.scale+extremum.x.min;
			}
        });
		/*
		for(var i=0;i<data.length;i++){
			var tempExtremum = {x:{min:Number.MAX_VALUE,max:Number.MIN_VALUE},y:{min:Number.MAX_VALUE,max:Number.MIN_VALUE}};
			for(var j=0;j<data[i].length;j++){
				dx = data[i][j][0];
				dy = data[i][j][1];
				
				if(tempExtremum.x.max<dx){
					tempExtremum.x.max = dx;
				}
				if(tempExtremum.x.min>=dx){
					tempExtremum.x.min = dx;
				}
				if(tempExtremum.y.max<dy){
					tempExtremum.y.max = dy;
				}
				if(tempExtremum.y.min>=dy){
					tempExtremum.y.min = dy;
				}
			}
			tempExtremum.x.max = this.axis.x.getCanvasPositionByPrice(tempExtremum.x.max);
			tempExtremum.x.min = this.axis.x.getCanvasPositionByPrice(tempExtremum.x.min);
			tempExtremum.y.max = this.axis.y.getCanvasPositionByPrice(tempExtremum.y.max);
			tempExtremum.y.min = this.axis.y.getCanvasPositionByPrice(tempExtremum.y.min);
			this.rects.push(tempExtremum);
		}
		*/
	},
	_drawingWorldMap:function(data){
		var cx = this.context;
		cx.save();
        cx.clearRect(0, 0, this.cfg.canvasWidth, this.cfg.canvasHeight);
		this._drawWorldMapLine(cx,data);
		for(var i in data){
			 var tempColor = this.cfg.color.worlmapColors[i]?this.cfg.color.worlmapColors[i]:this.cfg.color.worlmapColors[0];
			 if(i.indexOf("Space")>0){
				tempColor="#ffffff";
			 }
			 this._drawWorldMapMontain(cx,data[i],tempColor);
		}
		cx.restore();
	},
	_drawWorldMapMontain:function(cx,data,color,globalAlpha){
		cx.fillStyle = color;
		//cx.globalAlpha=globalAlpha||0.3;
		cx.beginPath();
		cx.moveTo(this.axis.x.getCanvasPositionByPrice(data[0][0]), this.axis.y.getCanvasPositionByPrice(data[0][1]));
		this._loopDrawing(cx,data);
		cx.lineTo(this.axis.x.getCanvasPositionByPrice(data[0][0]), this.axis.y.getCanvasPositionByPrice(data[0][1]));
		cx.fill();
		cx.globalAlpha=1;
		
	},
	setLineWidth:function(width){
		this.cfg.lineWidth =width||1;
	},
	_drawWorldMapLine:function(cx,data){
		//montain
		var color = this.cfg.color;
		cx.strokeStyle=color.line;
		cx.lineWidth=this.cfg.lineWidth;
		cx.lineCap  = "round";
		for(var i in data){
		cx.beginPath();
		cx.beginPath();
			cx.moveTo(this.axis.x.getCanvasPositionByPrice(data[i][0][0]), this.axis.y.getCanvasPositionByPrice(data[i][0][1]));
			this._loopDrawing(cx,data[i]);
			cx.lineTo(this.axis.x.getCanvasPositionByPrice(data[i][0][0]), this.axis.y.getCanvasPositionByPrice(data[i][0][1]));
			cx.stroke();
		}
		
		//cx.stroke();
        
	},
	drawMutiChart:function(dataList){
		if(!d){
			return;
		}
		if(this.timeObj){
			clearInterval(this.timeObj);
		}
		this.dataList=dataList;
		this._checkConfig();
		this._parseMutiData(dataList);
		var cx = this.context;
		cx.save();
		this._drawCoordinates(cx);
		for(var i=0,l=dataList.length;i<l;i++){
			 this._drawLine(cx,dataList[i].data,dataList[i].styleCfg);
		}
		this._drawXY(cx);
		cx.restore();
	},
    drawChart: function(d){
		var self = this;
		if(!d){
			return;
		}
		if(this.timeObj){
			clearInterval(this.timeObj);
		}
		this.data = d;
//		for(var i=0;i<d.data.length;i++){
//			this.data.data[i][1]=NaN;
//		}
		this._checkConfig();
		//this._getMaxLength(d.data);
		if(this.cfg.showYScaleNumber&&!this.cfg.customLabel){
			this.axis.x.margin=this._measureTextWidth(this._getMaxLength(d.data))+10;
		}else{
			this.axis.x.margin=0;
		}
        this._parseData(d);
        this._drawing(d.data);
    },
	_getMaxLength:function(d){
		var len = d.length;
		var max = 0,temp="";
		for(var i =0;i<len;i++){
			temp = d[i][1]+"";
			if(typeof(temp)=="undefined"||isNaN(temp)){
				continue;
			}
			temp = d[i][1].toFixed(this.cfg.percision[1])+"";
			if(max<temp.length){
				max = i;
			}
		}
		return len==0||d[max][1]==null||isNaN(d[max][1])?20:d[max][1].toFixed(this.cfg.percision[1]);
	},
	_checkConfig:function(){
		var cfg = this.cfg;
		if(!cfg.showX){
			this.axis.x.margin=0;
		}
		if(!cfg.showY){
			this.axis.y.margin=0;
		}
	},
	changeOutSize:function(w,h){
		if(w){
			this.canvas.width=w;
			this.cfg.canvasWidth = w;
		}
		if(h){
			this.canvas.height=h;
			this.cfg.canvasHeight = h;
		}
		if (this.data||this.dataList) {
			if(this.cfg.worldmap){
				this.drawWorldMap(this.data);
			}else{
				if(this.data){
					this.drawChart(this.data);
				}else{
					this.drawMutiChart(this.dataList);
				}
			}
		}
	},
	_drawLeftXY:function(cx){
		
	},
	_drawCoordinates:function(cx){
		cx.clearRect(0, 0, this.cfg.canvasWidth, this.cfg.canvasHeight);
		if(this.cfg.align=="left"){
			cx.translate(this.axis.x.margin, 0);
		}
		cx.lineWidth=1;
		cx.strokeStyle=this.cfg.color.axisColor;
		cx.beginPath();
		if (this.cfg.showY){
            if (this.cfg.align == "left") {
                cx.moveTo(0, 0);
                cx.lineTo(0, this.cfg.canvasHeight - this.axis.y.margin);
            }else{
				var x = this.cfg.canvasWidth-this.axis.x.margin;
				cx.moveTo(x,0);
                cx.lineTo(x,this.cfg.canvasHeight - this.axis.y.margin);
			}
		}
		if(this.cfg.showX){
			if (this.cfg.align == "left") {
				var y = this.cfg.canvasHeight-this.axis.y.margin;
				cx.moveTo(0,y);
                cx.lineTo(this.cfg.canvasWidth,y);
			}else{
				var y = this.cfg.canvasHeight-this.axis.y.margin;
                cx.moveTo(0,y);
                cx.lineTo(this.cfg.canvasWidth-this.axis.x.margin,y);
			}
		}
		cx.stroke();
	},
	_drawByLineType:function(cx,data){
		if(this.cfg.lineType=="line"){
			this._drawLine(cx,data);
			this._drawXY(cx);
		}else if(this.cfg.lineType=="montain"){
			this._drawMontain(cx,data);
			this._drawXY(cx);
		}else if(this.cfg.lineType=="block"){
            this._drawBlock(cx,data);
			this._drawXY(cx);
        }
	},
	_drawing:function(data){
		var cx = this.context;
		cx.save();
		this._drawCoordinates(cx);
        this._drawByLineType(cx,data);
		cx.restore();
	},
	_drawLine:function(cx,data,styleCfg){
		if(data.length==0) return;
		styleCfg=styleCfg||{};
		//montain
		var color = styleCfg.color||this.cfg.color;
		cx.strokeStyle=color.line;
		cx.lineWidth=this.cfg.lineWidth;
		cx.beginPath();
		cx.moveTo(0, this.axis.y.getCanvasPositionByPrice(data[0][1]));
		this._loopDrawing(cx,data);
		cx.stroke();
        
	},
	_formatYScal:function(n){
		var returnValue=0;
		if(this.cfg.percision[1]==0&&typeof(QS_NumFmt)!="undefined"&&typeof(QS_NumFmt.Fmt2)=="function"){
			returnValue = QS_NumFmt.Fmt2(n,false,"",this.cfg.percision[0],true);
		}else{
			returnValue = QS_NumberFormatter(n,null,null,this.cfg.percision[1]);
		}
		if(this.cfg.showYPlus){
			returnValue = ((returnValue>0?"+":"")+returnValue);
		}
		if(this.cfg.showYPrecent){
			returnValue +="%";
		}
		return returnValue;
	},
	_drawXY:function(cx){
		var color = this.cfg.color;
		cx.font = '11px Verdana';
        cx.textBaseline = 'top';
        cx.fillStyle = this.cfg.color.textColor;
        marginTop=this.cfg.marginTop||8;
        if(!this.cfg.showYScale){
        	marginTop -=8;
        }
        cx.beginPath();
        cx.strokeStyle=color.axisColor;
        var tempY = null,tempX=0,yaxisX=0;
		if(this.cfg.align=="right"){
			yaxisX=this.cfg.canvasWidth-this.axis.x.margin;
		}
		var ylabelContainer=this.cfg.customYLabelContainer?this.cfg.customYLabelContainer:this.container;
		var ylabelW=ylabelContainer.width();
		ylabelContainer.find(".qs-minichart-label").remove();
		this.container.find(".qs-minichart-label").remove();
        for(var i =0;i<this.axis.y.scaleList.length;i++){
            tempY = this.axis.y.getCanvasPositionByPrice(this.axis.y.scaleList[i]);
            if(this.cfg.align=="left"){
                
                if (this.cfg.showYScale) {
                    cx.moveTo(-3, tempY);
                    cx.lineTo(3, tempY);
                }
                if ((this.cfg.showY||this.cfg.showYScaleNumber)&&!isNaN(tempY)) {
					if(typeof(cx.fillText)!="function"||this.cfg.customLabel){

						ylabelContainer.append("<div class='qs-minichart-label' style='width:"+(ylabelW)+"px;position:absolute;left:"+(yaxisX+3)+"px;top:"+(tempY+marginTop)+"px;'>"+this._formatYScal(this.axis.y.scaleList[i])+"</div>");
					}else{
						cx.fillText(this._formatYScal(this.axis.y.scaleList[i]), -this.axis.x.margin, tempY);
					}
                }
            }else{
                if (this.cfg.showYScale) {
                    cx.moveTo(yaxisX-3, tempY);
                    cx.lineTo(yaxisX+3, tempY);
                }
                if ((this.cfg.showY||this.cfg.showYScaleNumber)&&!isNaN(tempY)) {
                    if (typeof(cx.fillText) != "function"||this.cfg.customLabel) {
                        ylabelContainer.append("<div class='qs-minichart-label' style='position:absolute;left:" + (yaxisX + 3) + "px;top:" + (tempY + marginTop) + "px;'>" + this._formatYScal(this.axis.y.scaleList[i]) + "</div>");
                    } else {
                        cx.fillText(this._formatYScal(this.axis.y.scaleList[i]), yaxisX + 3, tempY);
                    }
					
                }
            }
        }
        cx.stroke();
        cx.textAlign="left";
        cx.beginPath();
        tempY = this.cfg.canvasHeight - this.axis.y.margin;
		var i =0;
        if(this.cfg.showX){
			if(this.axis.x.scaleList.length>2){
                if((this.axis.x.scaleList[2][0]-this.axis.x.scaleList[1][0])/(this.axis.x.scaleList[1][0]-this.axis.x.scaleList[0][0])>2){
                    i=1;
                }
            }
			var _alternateXlable = 0;
			var _tempMap = null;
			if(this.cfg.xLableCount>-1){
				_tempMap = this._getXLableGap(this.axis.x.scaleList,this.cfg.xLableCount);
			}
            for (; i < this.axis.x.scaleList.length; i++) {
                tempX = this.axis.x.getCanvasPositionByPrice(this.axis.x.scaleList[i][0]);
                if (this.cfg.align == "left") {
                    
                    if (this.cfg.showXScale) {
                        cx.moveTo(tempX, tempY + 2);
                        cx.lineTo(tempX, tempY - 2);
                    }
                    if (this.cfg.showX) {
						if(this.cfg.xLableCount==-1&&this.cfg.xLableMinWidth>50&&this.cfg.canvasWidth<this.cfg.xLableMinWidth&&i==1){
							
						}else if(this.cfg.xLableCount==-1&&this.cfg.alternateXLable&&_alternateXlable%2==1){
							_alternateXlable++;
						}else{
							if(this.cfg.xLableCount>-1&&_tempMap&&!_tempMap.hasOwnProperty(i)){
								continue;
							}
							if (typeof(cx.fillText)!="function"||this.cfg.customLabel) {
								this.container.append("<div class='qs-minichart-label' style='position:absolute;left:"+(tempX)+"px;top:"+(tempY+15)+"px;'>"+this.axis.x.scaleList[i][1]+"</div>");
							}else{
								cx.fillText(this.axis.x.scaleList[i][1], tempX, tempY + 3);
							}
							_alternateXlable++;
						}
						
                    }
                } else {
                    if (this.cfg.showXScale) {
                        cx.moveTo(tempX, tempY + 2);
                        cx.lineTo(tempX, tempY - 2);
                    }
                    if (this.cfg.showX) {
						if(this.cfg.xLableCount==-1&&this.cfg.xLableMinWidth>50&&this.cfg.canvasWidth<this.cfg.xLableMinWidth&&i==1){
								
						}else if(this.cfg.xLableCount==-1&&this.cfg.alternateXLable&&_alternateXlable%2==1){
							_alternateXlable++;
						}else{
							if(this.cfg.xLableCount>-1&&_tempMap&&!_tempMap.hasOwnProperty(i)){
								continue;
							}
							if (typeof(cx.fillText)!="function"||this.cfg.customLabel) {
								this.container.append("<div class='qs-minichart-label' style='position:absolute;left:"+(tempX)+"px;top:"+(tempY+15)+"px;'>"+this.axis.x.scaleList[i][1]+"</div>");
							}else{
								cx.fillText(this.axis.x.scaleList[i][1], tempX, tempY + 3);
							}
							_alternateXlable++;
						}
                    }
                }
            }
        }
        cx.stroke();
	},
	_getXLableGap:function(s,c){

        var total = s.length - 1;
		
        var map = {};
        var gap = Math.ceil(total / c);
		var i =0;
		if(c/s.length>0.7){
			gap=1;
			total++;
			i =Math.floor((total-c)/2);
			if(i<0){
				i=0;
			}
		}
        for (var j=0; i < total&&j<c;j++, i += gap) {
            map[i] = true;
        }
        return map;
	},
	_drawBlock:function(cx,data){
		cx.fillStyle="#156E9C";
        cx.moveTo(0, this.cfg.canvasHeight);
		var bl = this.data.blockLine;
		var d = data;
		var up=[],down=[],tup=[],tdown =[];
		for(var i = 0;i<d.length;i++){
			if(i==0){
				if(d[i][1]>bl){
					tup.push([0,0]);
				}else{
					tdown.push([0,0]);
				}
			}
			if(i+1<d.length-1){
				if(d[i][1]>bl){
                    tup.push(d[i]);
					if(d[i+1][1]<=bl){
						var x = this._getXaxisValueByY(d[i][0],d[i][1],d[i+1][0],d[i+1][1],bl);
						tup.push([x,bl]);
						tup.push([x,0]);
						up.push(tup);
						tup=[];
						tdown.push([x,0]);
						tdown.push([x,bl]);
					}
                }else{
                    tdown.push(d[i]);
					if(d[i+1][1]>bl){
                        var x = this._getXaxisValueByY(d[i][0],d[i][1],d[i+1][0],d[i+1][1],bl);
                        tdown.push([x,bl]);
						tdown.push([x,0]);
                        down.push(tdown);
                        tdown=[];
						tup.push([x,0]);
                        tup.push([x,bl]);
                    }
                }
			}
			if(i==d.length-1){
				if(d[i][1]>bl){
                    tup.push(d[i]);
                }else{
                    tdown.push(d[i]);
                }
				if(tup.length>0){
					tup.push([d[i][0],0]);
					up.push(tup);
				}else{
					tdown.push([d[i][0],0]);
                    down.push(tup);
				}
			}
		}
		var ti  =null,tj = null;
		cx.globalAlpha =0.7;
		cx.fillStyle = mstar.flotUtil.colorToRGB(this.cfg.color.blockUp,0.7);
		cx.strokeStyle = this.cfg.color.blockUpStroke;
        for (var i = 0; i < up.length; i++) {
            var ti = up[i];
            cx.beginPath();
            this._loopDrawing(cx, ti);
            cx.fill();
			cx.beginPath();
            this._loopDrawingBorder(cx, ti);
            cx.stroke();
        }
		cx.fillStyle = this.cfg.color.blockDown;
		cx.strokeStyle = this.cfg.color.blockDownStroke;
        for (var i = 0; i < down.length; i++) {
            var ti = down[i];
            cx.beginPath();
            this._loopDrawing(cx, ti);
            cx.fill();
			cx.beginPath();
            this._loopDrawingBorder(cx, ti);
            cx.stroke();
        }
		cx.beginPath();
		cx.lineWeight=1;
		cx.strokeStyle=this.cfg.color.blockLine;
		var tempYpos = this.axis.y.getCanvasPositionByPrice(bl);
		cx.moveTo(0,tempYpos);
		cx.lineTo(this.axis.x.getCanvasPositionByPrice(d[d.length-1][0]),tempYpos);
		cx.stroke();
	},
	_getXaxisValueByY:function(x1,y1,x2,y2,y){
		return (y*(x2-x1)+y2*x1-y1*x2)/(y2-y1);
	},
	_drawMontain:function(cx,data){
		if(!data.length) return;
		cx.fillStyle = this.cfg.color.line;
		cx.globalAlpha=0.3;
		cx.moveTo(0, this.cfg.canvasHeight-this.axis.y.margin);
		this._loopDrawing(cx,data);
		var lastValidateIndex = 0;
		for(var i=data.length-1;i>=0;i--){
			if(!isNaN(data[i][1])){
				lastValidateIndex=i;
				break;
			}
		}
		cx.lineTo(this.axis.x.getCanvasPositionByPrice(data[lastValidateIndex][0]), this.cfg.canvasHeight-this.axis.y.margin);
		cx.fill();
		cx.globalAlpha=1;
		this._drawLine(cx,data);
	},
	_loopDrawing:function(cx,data){
		for(var i=0;i<data.length;i++){
			if(isNaN(this.axis.y.getCanvasPositionByPrice(data[i][1]))){
				continue;
			}
            cx.lineTo(this.axis.x.getCanvasPositionByPrice(data[i][0]), this.axis.y.getCanvasPositionByPrice(data[i][1]));
		}
	},
	_loopDrawingBorder:function(cx,data){
		var j =0;
        for(var i=0;i<data.length;i++,j++){
            if(isNaN(this.axis.y.getCanvasPositionByPrice(data[i][1]))){
                continue;
            }
			if(j==1){
				cx.moveTo(this.axis.x.getCanvasPositionByPrice(data[i][0]), this.axis.y.getCanvasPositionByPrice(data[i][1]));
			}else if(j<data.length-1){
				cx.lineTo(this.axis.x.getCanvasPositionByPrice(data[i][0]), this.axis.y.getCanvasPositionByPrice(data[i][1]));
			}
        }
    },
	_calculateMaxMin:function(d){
		var data = d.data, len = data.length;
		var max =0,min=len?Number.MAX_VALUE:0,t=0;
		for(var i=0;i<len;i++){
			t=data[i][1];
			if(max<t){
				max=t;
			}
			if(min>t){
				min=t
			}
		}
		return {y:[min,max],x:[0,len]};
	},
	_parseMutiData:function(dList){
		var maxLength="";
		var len=dList.length;
		var maxmin=this._calculateMaxMin(dList[0]);
		var ymax=maxmin.y[1],ymin=maxmin.y[0],xmax=maxmin.x[1],xmin=maxmin.x[0];
		var maxLengthData=this._getMaxLength(dList[0].data);
		if(len>1){
			for(var i=1;i<len;i++){
				var temp=this._getMaxLength(dList[i].data);
				if(maxLengthData.length<temp.length){
					maxLengthData=temp;
				}
				maxmin=this._calculateMaxMin(dList[i]);
				ymax=Math.max(ymax,maxmin.y[1]);
				xmax=Math.max(xmax,maxmin.x[1]);
				ymin=Math.min(ymin,maxmin.y[0]);
				xmin=Math.min(xmin,maxmin.x[0]);
			}
		}
		if(!this.cfg.customYLabelContainer){
			this.axis.x.margin=this._measureTextWidth(maxLengthData)+10
		};
		this._extendAxisCfg({y:[ymin,ymax],x:[xmin,xmax]},dList[0]);
		
	},
	_parseData:function(d){
		var maxmin=this._calculateMaxMin(d);
		this._extendAxisCfg(maxmin,d);
	},
	_getInterScale :function(value,celling){
        var res = 10;
        while (res < value)
        {
             res *= 10;
        }

        res = res / 10;
        if (res >= 1000)
        {
             res /= 10;
        }

        if ((value) % res == 0)
        {
             return value;
        }

        var tmp1 = (value) / res;
        if (celling) tmp1=Math.ceil(tmp1);
        value = tmp1 * res;
        return value;
	},
	getScale:function(min, max, minCount,insidePercent){
	    var scale =0;
	    if (isNaN(min) || isNaN(max) || min > max)
	    {
	        scale = 0;
	        return;
	    }
	    if (min == max){
	        min = min / 2.0;
	        max = max + min;
	    }
	    var diff = max - min,temp=0;
	    scale = diff / minCount;
	    if (scale <= 1)
	    {
	        var curValue = scale;
	        if(curValue>0.75){
	        	scale = 1;
	        	temp = 0.25;
	        }if(curValue>0.5){
	        	scale = 0.75;
	        	temp = 0.25;
	        }else if (curValue > 0.25){
	            scale = 0.5;
	            temp = 0.25;
	        }else if (curValue > 0.1){
	            scale = 0.25;
	            temp = 0.1;
	        }else if (curValue > 0.025){
	            scale = 0.05;
	            temp = 0.01;
	        }else{
	            scale = 0.005;
	            temp = 0.001;
	            while (scale > curValue){
	                scale -= 0.001;
	                temp -= 0.0001;
	            }
	            scale = scale < 0.001 ? 0.001 : scale;
	        }
	    }else{
	        if (scale <= 2){
	            scale = 2;
	            temp = 0.5;
	        }else if(scale<=5){
	        	scale = 5;
	        	temp = 0.5;
	        }else if(scale<=10){
	        	scale = 10;
	        	temp = 0.5;
	        }else {
	            scale = this._getInterScale(scale, true);
	            temp = scale/2;
	        }
	    }
	    var rangScole=[];
	    var maxTmp = Math.ceil(max / scale) * scale;
	    if (maxTmp == max){
	        maxTmp = max + scale;
	    }
	    var minTmp = Math.floor(min / scale) * scale;
	    if (minTmp == min){
	        minTmp = min - scale;
	    }
	    /*
	    if((min-minTmp)/min<insidePercent){
	    	minTmp = min - scale;
	    }
	    */
	    var tempTmp=minTmp+minCount*scale;
	    while(tempTmp<maxTmp){
	    	scale=scale+temp;
	    	tempTmp=minTmp+minCount*scale;
	    }
	    maxTmp=tempTmp;
	    return {max:maxTmp,min:minTmp,scale:scale};
	},
	_extendAxisCfg:function(maxmin,d){
		var max=maxmin.y[1],min=maxmin.y[0],self=this;
		if(this.cfg.showX){
			this.axis.x.scaleList=d.xAxis;
		}else{
			this.axis.y.margin=0;
		}
		var Yscale=this.getScale(min,max,this.axis.y.scaleCount+1,this.axis.y.insidePercent);//scale: price/pix
		min=Yscale.min,max=Yscale.max;
		this.axis.y.scaleList=[];
		for(var i =1;i<this.axis.y.scaleCount+2;i++){
			this.axis.y.scaleList.push(min+i*Yscale.scale);
		}
        $.extend(true, this.axis.y, {
            max: max,
            min: min,
            scale: (this.cfg.canvasHeight -this.axis.y.margin)/ (max - min),
            getCanvasPositionByPrice: function(p){
                return self.cfg.canvasHeight -self.axis.y.margin - (p -min)* self.axis.y.scale;
            }
        });
        $.extend(true, this.axis.x, {
            max: maxmin.x[1],
            min: maxmin.x[0],
            scale: (this.cfg.canvasWidth-this.axis.x.margin) / (maxmin.x[1] - maxmin.x[0]),
            getCanvasPositionByPrice: function(p){
                return p * self.axis.x.scale;
            }
        });
	},
    __init: function(){
        this.__createCanvas();
		//this.showLoading();
    },
	
	showLoading:function(){
        var self = this;
        var index = 0;
        var cx = self.context;
        cx.save();
        //cx.translate(self.axis.x.margin, 0);
        var txt = ["l", "o", "a", "d", "i", "n", "g"];
        var pos = [9, 18, 16, 17, 9, 18, 16];
        var cs = ["#38d302", "#30b702", "#299d01", "#207d00", "#299d01", "#30b702", "#38d302"].reverse();
        cx.fillStyle = '#156E9C';
        cx.font = 'bold 26px Verdana';
        cx.textBaseline = 'top';
        this.timeObj = setInterval(function(){
            var xpos = 0;
            cx.clearRect(0, 0, self.cfg.canvasWidth, self.cfg.canvasHeight);
            for (var i = 0; i < txt.length; i++) {
                var ci = 0;
                cx.beginPath();
                ci = index + i;
                if (ci > 6) {
                    ci = ci - 7;
                }
                cx.fillStyle = cs[ci];
                cx.fillText(txt[i], xpos, 10);
                xpos += pos[i];
                cx.stroke();
            }
            index++;
            if (index == 7) {
                index = 0;
            }
            
        }, 200);
        //cx.restore();
	},
	_measureTextWidth:function(text){
		if(this.measureTextWidthDom==null||this.measureTextWidthDom.length==0){
			this.measureTextWidthDom = $("<span style='position:absolute;left:-2000px;top:-2000px;display:none;'></span>").appendTo(document.body);
		}
		this.measureTextWidthDom.html(((this.cfg.showYPlus?"+":"")+text+(this.cfg.showYPrecent?"%":"")));
		return this.measureTextWidthDom.width();
	},
    __createCanvas: function(){
		var bIsIE = $.browser.msie;
        if(bIsIE&&parseInt($.browser.version)<9) { 
            window.G_vmlCanvasManager.init_(document); 
        }
        var canvas = document.createElement("canvas");
        canvas.width = this.cfg.canvasWidth;
        canvas.height = this.cfg.canvasHeight;
        this.canvas = canvas;
        this.el = $(this.canvas).appendTo(this.container);
        if (bIsIE&&parseInt($.browser.version)<9) { // excanvas 
            this.canvas = window.G_vmlCanvasManager.initElement(this.canvas); 
        }
        this.context = this.canvas.getContext("2d");
    }
};

    function getTicks(list,freq) { 
	   var frequencyMap={minute:1,minute5:5,minute10:10,minute15:15,minute30:30,d:"d",w:"w",m:"m"};
        if(list == null || list.length<1) return null;
        this.xLabelAlign = "left";
        var lg = list.length,dx,temp,vty=0,f=1;
        if(!isNaN(frequencyMap[freq])){  // minutely intraday data.
            dx=(list[lg-1][list[lg-1].length-1] - list[0][list[0].length-1])/86400000;
            temp = new Date(list[0][list[0].length-1]);
            f = Math.round(list.length/(dx*0.7));
        }else{
            vty = 1;
            dx = list[lg-1][list[lg-1].length-1] - list[0][list[0].length-1];
            temp = RTQ_ChartUtil.toDateFromIndex(list[0][list[0].length-1]);
        }
        var ty = "d", xx =1;
        var t = [];
		var iiii = 1;
        if (dx < 8) {
            ty = "d", t.push([0,DTFormat.ToMonthDate(temp)]);
            //this.xLabelAlign="center";
        } else if (dx <= 31) {
            ty ="avg",  t.push([0,DTFormat.ToMonthDate(temp)]);
			xx =5;
			iiii=xx;
            //this.xLabelAlign="center";
        } else if (dx <= 61) {
            ty="w",  t.push([0,DTFormat.ToMonthDate(temp)]);
        } else if (dx <= 240) {
            ty="m", t.push([0,(temp.getMonth()==0?temp.getFullYear():DTFormat.Mo[temp.getMonth()])]);
//			xx =15;
//            iiii=xx;
            //this.xLabelAlign="center";
        } else if (dx <= 730) {
            ty="q";   t.push([0,(temp.getMonth()==0?temp.getFullYear():DTFormat.Mo[temp.getMonth()])]);
        } else if (dx<= 2920) {
            ty ="y",  t.push([0,temp.getFullYear()]);
            this.xLabelAlign="center";
        } else { 
            ty = "5y",  t.push([0,temp.getFullYear()]);
        }
        var wdays = freq=="w"?5:1;// weekly data only fri data.
        for (var i = iiii; i < lg;i+= xx) {
            var d = RTQ_ChartUtil.toDateFromIndexOrTick(list[i][list[i].length-1],vty);
            if ( ty == "d"||ty == "avg") {
                if(temp.getDate()!=d.getDate()){
                    temp = RTQ_ChartUtil.toDateFromIndexOrTick(list[i][list[i].length-1],vty);
                    t.push([i,DTFormat.ToMonthDate(temp)]);
                }           
            }  else if (ty == "w") { 
                if (temp.getDate()!=d.getDate()&&d.getDay() == wdays) {  // weekly data only fri data.
                    temp = RTQ_ChartUtil.toDateFromIndexOrTick(list[i][list[i].length-1],vty);
                     t.push([i,DTFormat.ToMonthDate(temp)]);
                } 
            } else if (ty == "m") { 
                if (temp.getMonth() != d.getMonth()) { 
                    temp = RTQ_ChartUtil.toDateFromIndexOrTick(list[i][list[i].length-1],vty);
                    t.push([i,(temp.getMonth()==0?temp.getFullYear():DTFormat.Mo[temp.getMonth()])]);
                }
            } else if (ty == "q") {
                if (((d.getMonth()+1)%3 == 1) && (temp.getMonth() != d.getMonth())) {
                    temp = RTQ_ChartUtil.toDateFromIndexOrTick(list[i][list[i].length-1],vty);
                    t.push([i,(temp.getMonth()==0?temp.getFullYear():DTFormat.Mo[temp.getMonth()])]);
                } 
            } else if (ty == "y") {
                if (temp.getFullYear() != d.getFullYear()) {
                    temp = RTQ_ChartUtil.toDateFromIndexOrTick(list[i][list[i].length-1],vty);
                    t.push([i,temp.getFullYear()]);
                }
            } else { 
                if ((temp.getFullYear() != d.getFullYear()) && (d.getFullYear()%5==0)) {
                    temp = RTQ_ChartUtil.toDateFromIndexOrTick(list[i][list[i].length-1],vty);
                    t.push([i,temp.getFullYear()]);
                } 
            }
        } 
        return t;
    }
	
